package com.yanqu.road.utils.redis;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import redis.clients.jedis.Jedis;

public class RedisLock {

    private static Logger LOG = LogManager.getLogger(RedisLock.class);

    // 锁状态标志
    private boolean locked = false;

    private static int DEFAULT_TIME_OUT = 5000000;

    private String key = null;

    private Jedis jedis = null;

    public RedisLock(String key, Jedis jedis) {
        this.jedis = jedis;
        this.key = key + "_lock";
    }

    /**
     * 加锁
     *
     * @param timeout
     * @return
     */
    private boolean lock(long timeout) {
        long enter = System.currentTimeMillis();
        try {
            while ((System.currentTimeMillis() - enter) < timeout) {
                if (jedis.setnx(key, "true") == 1) {
                    jedis.expire(key, DEFAULT_TIME_OUT);
                    locked = true;
                    return locked;
                }
                // 短暂休眠，nano避免出现活锁
                Thread.sleep(50);
            }

        } catch (Exception e) {
            LOG.error(key, e);
        }
        return false;
    }


    public boolean lock() {
        return lock(DEFAULT_TIME_OUT);
    }

    /**
     * 解锁
     */
    public void unlock() {
        // 无论是否加锁成功，必须调用
        try {
            if (locked) {
                jedis.del(key);
            }
        } finally {
            jedis.close();
        }
    }
}
